<?php
/**
 *    Copyright 2010 Show Framework(www.showframework.cn)
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 * 
 *        http://www.apache.org/licenses/LICENSE-2.0
 * 
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 * Show_Db_Handle_Mysql
 * 使用Mysql底层函数实现的数据库驱动
 * 
 * @package Show_Db_Handle
 * @name Show_Db_Handle_Mysql
 * @author show
 * @since v0.6
 */
class Show_Db_Handle_Mysql implements Show_Db_Handle_Interface
{
    /**
     * MySQL连接ID
     * MySQL link identifier
     *
     * @var resource
     */
    protected $link;
    
    /**
     * 上一次查询是否成功的标识
     *
     * @var bool
     */
    protected $lastQueryOk;
    
    /**
     * 上一次查询结果资源
     * resource:SELECT, SHOW, DESCRIBE, EXPLAIN, etc
     * bool:INSERT, UPDATE, DELETE, DROP, etc
     *
     * @var resource|bool
     */
    protected $queryResult;
    
    /**
     * Show_Db_Handle_Mysql
     *
     * @param string $host
     * @param string $user
     * @param string $pass
     * @param string $db
     * @return Show_Db_Handle_Interface
     */
    public function __construct($host, $user, $pass, $db = null)
    {
        $this->lastQueryOk = false;
        $this->link = mysql_connect($host, $user, $pass);
        if ($this->link === false) {
        	trigger_error(mysql_error(), E_USER_ERROR);
        } elseif (isset($db)) {
        	$this->db($db);
        }
    }
    
    /**
     * Get number of affected rows in previous MySQL operation
     * Returns the number of rows affected by the last INSERT, UPDATE, REPLACE or DELETE query.
     * > 0 
     * 0 no records affected
     * -1 error
     * 
     * @return int
     */
    public function affected()
    {
        return mysql_affected_rows($this->link);
    }
    
    /**
     * Closes a previously opened database connection
     *
     * @return bool
     */
    public function close()
    {
        return mysql_close($this->link);
    }
    
    /**
     * Move internal result pointer
     * Returns TRUE on success or FALSE on failure. 
     *
     * @param int $offset
     * @return bool
     */
    public function seek($offset)
    {
        return $this->lastQueryOk ? mysql_data_seek($this->queryResult, $offset) : false;
    }
    
    /**
     * Returns the numerical value of the error message from previous MySQL operation
     * zero means no error occurred.
     *
     * @return int
     */
    public function errno()
    {
        return mysql_errno($this->link);
    }
    
    /**
     * Returns the text of the error message from previous MySQL operation
     * An empty string if no error occurred.
     *
     * @return string
     */
    public function error()
    {
        return mysql_error($this->link);
    }
    
    /**
     * Fetch a result row as an associative array, a numeric array, or both or object
     * 
     * @param int $fetchMode
     * @return array|object|false
     */
    public function fetch($fetchMode = Show_DB::FETCH_ASSOC)
    {
        return $this->lastQueryOk ? ($fetchMode === Show_Db::FETCH_OBJ ? mysql_fetch_object($this->queryResult) : mysql_fetch_array($this->queryResult, $fetchMode)) : false;
    }
    
    /**
     * Frees the memory associated with a result
     * 
     * @return bool
     */
    public function free()
    {
        return $this->lastQueryOk ? mysql_free_result($this->queryResult) : true;
    }
    
    /**
     * Get the ID generated from the previous INSERT operation
     * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
     * > 0 or 0
     *
     * @return int
     */
    public function insertId()
    {
        return mysql_insert_id($this->link);
    }
    
    /**
     * Gets the number of rows in a result
     * > 0 or 0
     *
     * @return int
     */
    public function rows()
    {
        return $this->lastQueryOk ? mysql_num_rows($this->queryResult) : 0;
    }
    
    /**
     * Send a SQL query
     *
     * @param string $sql
     * @return bool
     */
    public function query($sql)
    {
        $this->lastQueryOk = false;
        if (($this->queryResult = mysql_query($sql, $this->link)) !== false) {
            $this->lastQueryOk = true;
        }
        return $this->lastQueryOk;
    }
    
    /**
     * Escapes special characters in a string for use in a SQL statement
     *
     * @param string $string
     * @return string
     */
    public function escape($string)
    {
        return mysql_real_escape_string($string, $this->link);
    }
    
    /**
     * Selects the default database for database queries
     *
     * @param string $name
     * @return bool
     */
    public function db($name)
    {
        return mysql_select_db($name, $this->link);
    }
    
    /**
     * Sets the client character set
     *
     * @param string $charset
     * @return bool
     */
    public function charset($charset)
    {
        return mysql_set_charset($charset, $this->link);
    }
}
?>